using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Animation;

namespace Silvery
{
    /// <summary>
    /// 能够移动接口
    /// </summary>
    public interface ICanMove : IBaseObject
    {
        void MoveTo(Point from, Point to, double speed = GlobleConfig.DefaultObjectMoveCost);
        Storyboard MoveStoryboard { get; }
        event MoveCompletedEventHandler MoveCompleted;
        /// <summary>
        /// 每秒钟的移动速度
        /// </summary>
        double Speed { get; set; }
        List<Point> GotoQueue { get; set; }
    }
    public delegate void MoveCompletedEventHandler(MoveObject moveobj);
    public abstract class MoveObject : BaseObject, ICanMove
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public MoveObject()
        {
            MoveStoryboard = new Storyboard();
            PointAnimation pointAnimation = new PointAnimation();
            Storyboard.SetTarget(pointAnimation, this);
            Storyboard.SetTargetProperty(pointAnimation, new PropertyPath("Position"));
            MoveStoryboard.Children.Add(pointAnimation);
            MoveStoryboard.Completed += new EventHandler(MoveStoryboard_Completed);
            Speed = GlobleConfig.DefaultObjectMoveCost;
        }

        void MoveStoryboard_Completed(object sender, EventArgs e)
        {
            if (_GotoQueue == null)
            {
                MoveObjectStop();
                return;
            }
            if (_GotoQueue.Count <= 0)
                MoveObjectStop();
            else
            {
                var ep = _GotoQueue[0];
                _GotoQueue.RemoveAt(0);
                MoveTo(this.Position, ep, Speed);
            }
            
        }


        #region ICanMove Members
        List<Point> _GotoQueue = null;
        /// <summary>
        /// 移动队列
        /// </summary>
        public List<Point> GotoQueue
        {
            get { return _GotoQueue; }
            set 
            {
                if (_GotoQueue != null)
                    MoveObjectStop();
                _GotoQueue = value;
                if (value != null)
                {
                    if (_GotoQueue.Count > 1)
                    {
                        var startp1 = _GotoQueue[0];
                        var startp2 = _GotoQueue[1];
                        _GotoQueue.RemoveAt(0);
                        _GotoQueue.RemoveAt(0);
                        
                        MoveTo(startp1, startp2, Speed);
                    }
                    else
                    {
                        if (_GotoQueue.Count > 0)
                            Position = _GotoQueue[0];
                    }
                }
            }
        }
        public double Speed { get; set; }
        /// <summary>
        /// 移动停止
        /// </summary>
        public void MoveObjectStop()
        {
            if (MoveStoryboard.GetCurrentState() == ClockState.Stopped)
                return;
            MoveStoryboard.Pause();
            var temp = this.Position;
            MoveStoryboard.Stop();
            this.Position = temp;
            if(_GotoQueue!=null)
                if(_GotoQueue.Count<=0)
                    _GotoQueue = null;
            OnMoveCompleted();
        }
        protected virtual void OnMoveCompleted()
        {
            if (MoveCompleted != null)
                MoveCompleted(this);
        }
        /// <summary>
        /// 移动完毕事件
        /// </summary>
        public event MoveCompletedEventHandler MoveCompleted; 
        /// <summary>
        /// 移动到
        /// </summary>
        /// <param name="from">从什么地方开始</param>
        /// <param name="to">到什么地方</param>
        /// <param name="cost">速度设置</param>
        public virtual void MoveTo(Point from, Point to, double speed = GlobleConfig.DefaultObjectMoveCost)
        {            
            Speed = speed;
            MoveObjectStop();
            var duration = new Duration(TimeSpan.FromSeconds(GetTwoPointDistance(from, to) / speed));
            MoveStoryboard.Duration = duration;
            var pointAnimation = (MoveStoryboard.Children[0] as PointAnimation);
            pointAnimation.From = from;
            pointAnimation.To = to;
            pointAnimation.Duration = duration;
            MoveStoryboard.Begin();
        }
        /// <summary>
        /// 获得移动的故事板
        /// </summary>
        public Storyboard MoveStoryboard { get; private set; }
        #endregion
        /// <summary>
        /// 销毁，已经重载
        /// </summary>
        public override void Dispose()
        {
            if (MoveStoryboard != null)
            {
                MoveStoryboard.Completed -= MoveStoryboard_Completed;
                MoveStoryboard.Stop();
                MoveStoryboard.Children.Clear();
                MoveStoryboard = null;
            }
            if (_GotoQueue != null)
                _GotoQueue.Clear();
            _GotoQueue = null;
            base.Dispose();
        }
        /// <summary>
        /// 获取两点之间距离
        /// </summary>
        /// <param name="p1">点1</param>
        /// <param name="p2">点2</param>
        /// <returns>两点之间距离</returns>
        public static double GetTwoPointDistance(Point p1, Point p2)
        {
            return Math.Sqrt(Math.Pow((p1.X - p2.X), 2) + Math.Pow((p1.Y - p2.Y), 2));
        }
    }
}
